import { queryCompanies } from '@/pages/SystemUser/service';
import { Role } from '@/utils/types.d';
import {
  ProForm,
  ModalForm,
  ProFormGroup,
  ProFormList,
  ProFormSelect,
  ProFormSwitch,
  ProFormText,
  ProFormTextArea,
  ProCard,
} from '@ant-design/pro-components';
import { Button, InputNumber, message, Switch, TimePicker } from 'antd';
import { useModel } from 'umi';
import style from '../styles.less';
import type { ChargeFrameItem, CreateChargeRule } from '../types.d';
import { createChargeRule } from '../service';
import { PlusOutlined } from '@ant-design/icons';
import { handleTimes, specialCharReg } from '@/utils/utils';
import { useState } from 'react';
import { getDayHour, transformFrames } from '../utils';

const ConfigChargeRule = (props: { reload: () => void }) => {
  const { initialState } = useModel('@@initialState');
  const userRole = initialState?.currentUser?.role;
  const [form] = ProForm.useForm();
  const [ifLarge, setIfLarge] = useState<boolean>(false);
  const [isSection, setIsSection] = useState<boolean>(false);
  const [sectionTime, setSectionTime] = useState<number>(30);

  return (
    <ModalForm<CreateChargeRule>
      title="配置收费规则"
      className={style.easyModal}
      width={980}
      form={form}
      modalProps={{
        destroyOnClose: true,
        maskClosable: false,
      }}
      layout="horizontal"
      trigger={
        <Button type="primary">
          <PlusOutlined /> 创建
        </Button>
      }
      onFinish={async (values) => {
        const { name, description, ownerId, commonLarge, commonSmall, calcType } = values;

        const smallFreeTimes = handleTimes(commonSmall?.freeTimes || []);
        const largeFreeTimes = handleTimes(commonLarge?.freeTimes || []);
        // const freetimes = handleTimes(values.freeTimes || []);
        const data2create: CreateChargeRule = {
          name: name,
          description: description,
          ownerId: ownerId,
          section: isSection,
          calcType: calcType,
          mode: values.mode || 0,
          commonSmall: {
            freeMin: commonSmall?.freeMin || 0,
            dayMax: commonSmall?.dayMax || 0,
            freeTimes: smallFreeTimes,
            chargeFrames: transformFrames(commonSmall?.chargeFrames || [], isSection, sectionTime),
          },
          //   firstHour: values.firstHour,
          //   freeMin: values.freeMin,
          //   freeTimes: freetimes,
          //   afterHours: values.afterHours || 0,
          //   dayMax: values.dayMax,
          //   chargeFrames: values.chargeFrames || [],
        };
        if (ifLarge) {
          data2create.commonLarge = {
            freeMin: commonLarge?.freeMin || 0,
            dayMax: commonLarge?.dayMax || 0,
            freeTimes: largeFreeTimes,
            chargeFrames: transformFrames(commonLarge?.chargeFrames || [], isSection, sectionTime),
          };
        }
        const res = await createChargeRule(data2create);
        if (res.success) {
          message.success({ key: 'config_rules', content: res.message });
          props.reload();
          return true;
        }
        message.error({ key: 'config_rules', content: res.message });
        return false;
      }}
    >
      {userRole === Role.ADMIN && (
        <ProFormSelect
          labelCol={{ span: 3 }}
          wrapperCol={{ span: 19 }}
          name="ownerId"
          label="归属公司"
          debounceTime={300}
          showSearch
          placeholder="请选择归属公司(如未找到目标公司，请优先创建[企业管理者])"
          request={(val) => queryCompanies(val.keyWords)}
        />
      )}
      <ProFormText
        labelCol={{ span: 3 }}
        wrapperCol={{ span: 19 }}
        label="规则名称"
        name="name"
        rules={[
          {
            required: true,
            validator: (_, val) => {
              if (!val || specialCharReg.test(val))
                return Promise.reject(new Error('规则名称不符合规范，不支持包含特殊字符'));
              return Promise.resolve(val);
            },
          },
        ]}
        placeholder="请输入规则名称"
      />
      <ProFormTextArea
        labelCol={{ span: 3 }}
        wrapperCol={{ span: 19 }}
        label="规则描述"
        name="description"
        placeholder="请输入规则描述"
      />
      {/* <ProFormFieldSet
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 20 }}
        required
        label="小型车配置"
        type="group"
        transform={() => ({})}
      > */}
      <ProFormGroup style={{ marginLeft: '35px' }}>
        <ProFormSelect
          label="时间模式"
          required
          width="md"
          name="calcType"
          placeholder="请选择跨天时的计算模式"
          options={[
            {
              label: '按天计算(每日0:00 - 24:00视作一天)',
              value: 0,
            },
            {
              label: '按小时计算(24小时制, 满24小时视作一天)',
              value: 1,
            },
          ]}
        />
        <ProFormSelect
          label="ETC助缴"
          tooltip="ETC支付当前不支持退款操作，请谨慎开启"
          placeholder={'请选择是否支持ETC助缴'}
          name="mode"
          width="md"
          options={[
            {
              label: '关闭',
              value: 0,
            },
            {
              label: '开启',
              value: 1,
            },
          ]}
        />
      </ProFormGroup>

      <ProFormGroup style={{ marginLeft: '35px' }}>
        <ProFormSwitch
          label="整段计费"
          name="section"
          required
          fieldProps={{
            checked: isSection,
            onChange: (e) => setIsSection(e),
          }}
        />
        {isSection && (
          <ProFormSelect
            label="尾数时间: "
            required
            width="md"
            options={[
              { label: '0分钟', value: 0 },
              { label: '30分钟', value: 30 },
              { label: '60分钟', value: 60 },
            ]}
            fieldProps={{
              value: sectionTime,
              onChange: (v) => setSectionTime(v),
            }}
          />
        )}
      </ProFormGroup>

      <ProCard title="小型车配置" ghost style={{ maxWidth: 860, margin: '0 auto' }}>
        <ProForm.Group>
          <ProForm.Item
            label="免费时段"
            // labelCol={{ span: 4 }}
            name={['commonSmall', 'freeTimes']}
            tooltip="起始时间与结束时间相同时，表示无免费时段，全天收费"
            rules={[{ required: true, message: '请选择免费时段' }]}
          >
            <TimePicker.RangePicker
              order={false}
              format="HH:mm"
              placeholder={['起始时间', '结束时间']}
            />
          </ProForm.Item>

          <ProForm.Item
            label="免费时长"
            name={['commonSmall', 'freeMin']}
            rules={[
              {
                required: true,
                message: '请输入免费时长',
              },
            ]}
          >
            <InputNumber
              placeholder=""
              style={{
                width: '130px',
              }}
              className={style.freeMin}
              precision={0}
              min={0}
            />
          </ProForm.Item>
          <ProForm.Item
            label="最高限额"
            name={['commonSmall', 'dayMax']}
            rules={[
              {
                required: true,
                message: '请输入最高限额',
              },
            ]}
          >
            <InputNumber
              placeholder=""
              style={{
                width: '130px',
              }}
              className={style.rmb}
              precision={2}
              min={0}
            />
          </ProForm.Item>
        </ProForm.Group>

        {isSection ? (
          <ProFormList
            label={<span className={style.redStar}>时段规则</span>}
            name={['commonSmall', 'chargeFrames']}
            copyIconProps={false}
            min={0}
            max={5}
            rules={[
              {
                validator: (_, value: ChargeFrameItem[]) => {
                  try {
                    const originFreeTime = form.getFieldValue(['commonSmall', 'freeTimes']);

                    if (!originFreeTime) {
                      return Promise.reject(new Error('请优先配置规则免费时段'));
                    }
                    const dayHour = getDayHour(originFreeTime || []);

                    if (!value || value.length == 0 || value.length > 5) {
                      return Promise.reject(new Error('非法的时段规则配置'));
                    }
                    const i0 = value[0] || {};
                    if (i0.start !== 0) {
                      return Promise.reject(
                        new Error('时段规则必须从0到第n小时(含)开始配置(n >= 0)'),
                      );
                    }
                    const iLen = value[value.length - 1] || {};
                    if (iLen.end < dayHour) {
                      return Promise.reject(new Error('时段规则未覆盖全部收费时段'));
                    }
                    const checkItem = value.some((val) => Object.keys(val || {}).length < 3);
                    if (checkItem) {
                      return Promise.reject(new Error('不完整的配置，请完善时段规则或删除空项'));
                    }
                    if (value.length > 1) {
                      for (let i = 1; i < value.length; i++) {
                        const curr = value[i];
                        const prev = value[i - 1];
                        if (curr.start !== prev.end) {
                          return Promise.reject(new Error('时段规则不连续'));
                        }
                        if (curr.end <= curr.start) {
                          return Promise.reject(
                            new Error(
                              '错误的时段格式，请确保每一时段中的 起始时间 始终小于等于 终止时间 ',
                            ),
                          );
                        }
                      }
                    }
                  } catch (err) {
                    return Promise.reject(new Error(String(err)));
                  }
                  return Promise.resolve(value);
                },
              },
            ]}
            creatorRecord={{}}
            creatorButtonProps={{
              creatorButtonText: '添加时段规则',
              style: {
                marginBottom: 5,
              },
            }}
            style={{
              margin: '0 auto',
              width: '100%',
            }}
          >
            <ProFormGroup labelLayout="inline">
              <ProForm.Item label="" name="start" addonAfter="小时 -">
                <InputNumber placeholder="" precision={0} min={0} max={24} />
              </ProForm.Item>
              <ProForm.Item label="" name="end" addonAfter="小时(含)">
                <InputNumber placeholder="" precision={0} min={1} max={24} />
              </ProForm.Item>

              <ProForm.Item label="费用" name="price">
                <InputNumber placeholder="" className={style.rmb} precision={0} min={0} />
              </ProForm.Item>
            </ProFormGroup>
          </ProFormList>
        ) : (
          <ProFormList
            label={<span className={style.redStar}>时段规则</span>}
            name={['commonSmall', 'chargeFrames']}
            copyIconProps={false}
            min={0}
            max={5}
            rules={[
              {
                validator: (_, value: ChargeFrameItem[]) => {
                  try {
                    const originFreeTime = form.getFieldValue(['commonSmall', 'freeTimes']);

                    if (!originFreeTime) {
                      return Promise.reject(new Error('请优先配置规则免费时段'));
                    }
                    const dayHour = getDayHour(originFreeTime || []);

                    if (!value || value.length == 0 || value.length > 5) {
                      return Promise.reject(new Error('非法的时段规则配置'));
                    }
                    const i0 = value[0] || {};
                    if (i0.start !== 1) {
                      return Promise.reject(
                        new Error('时段规则必须从第1小时到第n小时开始配置(n >= 1)'),
                      );
                    }
                    const iLen = value[value.length - 1] || {};
                    if (iLen.end < dayHour) {
                      return Promise.reject(new Error('时段规则未覆盖全部收费时段'));
                    }
                    const checkItem = value.some((val) => Object.keys(val || {}).length !== 4);
                    if (checkItem) {
                      return Promise.reject(new Error('不完整的配置，请完善时段规则或删除空项'));
                    }
                    if (value.length > 1) {
                      for (let i = 1; i < value.length; i++) {
                        const curr = value[i];
                        const prev = value[i - 1];
                        if (curr.start !== prev.end + 1) {
                          return Promise.reject(new Error('时段规则不连续'));
                        }
                        if (curr.end < curr.start) {
                          return Promise.reject(
                            new Error(
                              '错误的时段格式，请确保每一时段中的 起始时间 始终小于等于 终止时间 ',
                            ),
                          );
                        }
                      }
                    }
                  } catch (err) {
                    return Promise.reject(new Error(String(err)));
                  }
                  return Promise.resolve(value);
                },
              },
            ]}
            creatorRecord={{}}
            creatorButtonProps={{
              creatorButtonText: '添加时段规则',
              style: {
                marginBottom: 5,
              },
            }}
            style={{
              margin: '0 auto',
              width: '100%',
            }}
          >
            <ProFormGroup labelLayout="inline">
              <ProForm.Item label="从第" name="start" addonAfter="小时开始">
                <InputNumber placeholder="" precision={0} min={1} max={23} />
              </ProForm.Item>
              <ProForm.Item label="到第" name="end" addonAfter="小时结束">
                <InputNumber placeholder="" precision={0} min={1} max={23} />
              </ProForm.Item>

              <ProFormSelect
                label="每"
                name="unit"
                options={[
                  { label: '半小时', value: 30 },
                  { label: '小时', value: 60 },
                ]}
              />
              <ProForm.Item label="价格" name="price">
                <InputNumber placeholder="" className={style.rmb} precision={2} min={0} />
              </ProForm.Item>
            </ProFormGroup>
          </ProFormList>
        )}
      </ProCard>
      {/* </ProFormFieldSet> */}
      {/* <ProFormFieldSet
        labelCol={{ span: 4 }}
        wrapperCol={{ span: 20 }}
        label="大型车配置"
        type="group"
        tooltip="若不配置则默认使用小型车相同配置"
        transform={() => ({})}
      > */}
      <ProCard
        title={
          <div style={{ display: 'flex', alignItems: 'center' }}>
            <span style={{ marginRight: '5px' }}>大型车配置</span>
            <Switch checked={ifLarge} onChange={() => setIfLarge(!ifLarge)} />
          </div>
        }
        ghost
        style={{ maxWidth: 860, margin: '0 auto' }}
        bodyStyle={{
          padding: '0 3px',
        }}
      >
        {ifLarge && (
          <>
            <ProForm.Group>
              <ProForm.Item
                label="免费时段"
                name={['commonLarge', 'freeTimes']}
                rules={[{ required: true, message: '请选择免费时段' }]}
              >
                <TimePicker.RangePicker
                  order={false}
                  format="HH:mm"
                  placeholder={['起始时间', '结束时间']}
                />
              </ProForm.Item>

              <ProForm.Item
                label="免费时长"
                name={['commonLarge', 'freeMin']}
                rules={[
                  {
                    required: true,
                    message: '请输入免费时长',
                  },
                ]}
              >
                <InputNumber
                  placeholder=""
                  style={{
                    width: '130px',
                  }}
                  className={style.freeMin}
                  precision={0}
                  min={0}
                />
              </ProForm.Item>
              <ProForm.Item
                label="最高限额"
                name={['commonLarge', 'dayMax']}
                rules={[
                  {
                    required: true,
                    message: '请输入最高限额',
                  },
                ]}
              >
                <InputNumber
                  placeholder=""
                  style={{
                    width: '130px',
                  }}
                  className={style.rmb}
                  precision={2}
                  min={0}
                />
              </ProForm.Item>
            </ProForm.Group>

            {isSection ? (
              <ProFormList
                label={<span className={style.redStar}>时段规则</span>}
                name={['commonLarge', 'chargeFrames']}
                copyIconProps={false}
                min={0}
                max={5}
                rules={[
                  {
                    validator: (_, value: ChargeFrameItem[]) => {
                      try {
                        const originFreeTime = form.getFieldValue(['commonLarge', 'freeTimes']);

                        if (!originFreeTime) {
                          return Promise.reject(new Error('请优先配置规则免费时段'));
                        }
                        const dayHour = getDayHour(originFreeTime || []);

                        if (!value || value.length == 0 || value.length > 5) {
                          return Promise.reject(new Error('非法的时段规则配置'));
                        }
                        const i0 = value[0] || {};
                        if (i0.start !== 0) {
                          return Promise.reject(
                            new Error('时段规则必须从0到第n小时(含)开始配置(n >= 0)'),
                          );
                        }
                        const iLen = value[value.length - 1] || {};
                        if (iLen.end < dayHour) {
                          return Promise.reject(new Error('时段规则未覆盖全部收费时段'));
                        }
                        const checkItem = value.some((val) => Object.keys(val || {}).length < 3);
                        if (checkItem) {
                          return Promise.reject(
                            new Error('不完整的配置，请完善时段规则或删除空项'),
                          );
                        }
                        if (value.length > 1) {
                          for (let i = 1; i < value.length; i++) {
                            const curr = value[i];
                            const prev = value[i - 1];
                            if (curr.start !== prev.end) {
                              return Promise.reject(new Error('时段规则不连续'));
                            }
                            if (curr.end <= curr.start) {
                              return Promise.reject(
                                new Error(
                                  '错误的时段格式，请确保每一时段中的 起始时间 始终小于等于 终止时间 ',
                                ),
                              );
                            }
                          }
                        }
                      } catch (err) {
                        return Promise.reject(new Error(String(err)));
                      }
                      return Promise.resolve(value);
                    },
                  },
                ]}
                creatorRecord={{}}
                creatorButtonProps={{
                  creatorButtonText: '添加时段规则',
                  style: {
                    marginBottom: 5,
                  },
                }}
                style={{
                  margin: '0 auto',
                  width: '100%',
                }}
              >
                <ProFormGroup labelLayout="inline">
                  <ProForm.Item label="" name="start" addonAfter="小时 -">
                    <InputNumber placeholder="" precision={0} min={0} max={24} />
                  </ProForm.Item>
                  <ProForm.Item label="" name="end" addonAfter="小时(含)">
                    <InputNumber placeholder="" precision={0} min={1} max={24} />
                  </ProForm.Item>

                  <ProForm.Item label="费用" name="price">
                    <InputNumber placeholder="" className={style.rmb} precision={0} min={0} />
                  </ProForm.Item>
                </ProFormGroup>
              </ProFormList>
            ) : (
              <ProFormList
                name={['commonLarge', 'chargeFrames']}
                label={<span className={style.redStar}>时段规则</span>}
                copyIconProps={false}
                min={0}
                max={5}
                rules={[
                  {
                    validator: (_, value: ChargeFrameItem[]) => {
                      try {
                        if (!ifLarge) {
                          return Promise.resolve(value);
                        }
                        const originFreeTime = form.getFieldValue(['commonLarge', 'freeTimes']);
                        if (!originFreeTime) {
                          return Promise.reject(new Error('请优先配置规则免费时段'));
                        }
                        const dayHour = getDayHour(originFreeTime || []);

                        if (!value || value.length == 0 || value.length > 5) {
                          return Promise.reject(
                            new Error('单独配置免费时段时,需要另行配置时段规则'),
                          );
                        }
                        const i0 = value[0] || {};
                        if (i0.start !== 1) {
                          return Promise.reject(
                            new Error('时段规则必须从第1小时到第n小时开始配置(n >= 1)'),
                          );
                        }
                        const iLen = value[value.length - 1] || {};
                        if (iLen.end < dayHour) {
                          return Promise.reject(new Error('时段规则未覆盖全部收费时段'));
                        }
                        const checkItem = value.some((val) => Object.keys(val || {}).length !== 4);
                        if (checkItem) {
                          return Promise.reject(
                            new Error('不完整的配置，请完善时段规则或删除空项'),
                          );
                        }
                        if (value.length > 1) {
                          for (let i = 1; i < value.length; i++) {
                            const curr = value[i];
                            const prev = value[i - 1];
                            if (curr.start !== prev.end + 1) {
                              return Promise.reject(new Error('时段规则不连续'));
                            }
                            if (curr.end < curr.start) {
                              return Promise.reject(
                                new Error(
                                  '错误的时段格式，请确保每一时段中的 起始时间 始终小于等于 终止时间 ',
                                ),
                              );
                            }
                          }
                        }
                      } catch (err) {
                        return Promise.reject(new Error(String(err)));
                      }
                      return Promise.resolve(value);
                    },
                  },
                ]}
                creatorRecord={{}}
                creatorButtonProps={{
                  creatorButtonText: '添加时段规则',
                  style: {
                    marginBottom: 5,
                  },
                }}
                style={{
                  margin: '0 auto',
                  width: '100%',
                }}
              >
                <ProFormGroup labelLayout="inline">
                  <ProForm.Item label="从第" name="start" addonAfter="小时开始">
                    <InputNumber placeholder="" precision={0} min={1} max={23} />
                  </ProForm.Item>
                  <ProForm.Item label="到第" name="end" addonAfter="小时结束">
                    <InputNumber placeholder="" precision={0} min={1} max={23} />
                  </ProForm.Item>

                  <ProFormSelect
                    label="每"
                    name="unit"
                    options={[
                      { label: '半小时', value: 30 },
                      { label: '小时', value: 60 },
                    ]}
                  />
                  <ProForm.Item label="价格" name="price">
                    <InputNumber placeholder="" className={style.rmb} precision={2} min={0} />
                  </ProForm.Item>
                </ProFormGroup>
              </ProFormList>
            )}
          </>
        )}
      </ProCard>
      {/* </ProFormFieldSet> */}
    </ModalForm>
  );
};

export default ConfigChargeRule;
